package br.com.tiespec.web.ManagedBean;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServletResponse;

import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;

import br.com.tiespec.ejb.EjbInterface.ImpressaoDescricaoInterface;
import br.com.tiespec.model.Enum.TipoSortOrder;
import br.com.tiespec.model.Modelo.Cenario;
import br.com.tiespec.model.Modelo.Dado;
import br.com.tiespec.model.Modelo.DescricaoEstendida;
import br.com.tiespec.model.Modelo.Fluxo;
import br.com.tiespec.model.Modelo.Projeto;
import br.com.tiespec.web.Util.InitUtil;
import br.com.tiespec.web.Util.PdfDescricao;
import br.com.tiespec.web.Util.WebUtil;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

@Named("impressaoBean")
@SessionScoped
public class ImpressaoBean implements Serializable {

	private static final long serialVersionUID = -7778863626034900205L;

	@EJB private ImpressaoDescricaoInterface ejb;
	@Inject private ContextoBean contexto;
	
	private Projeto pInstance;
	private Projeto pInstanceTemp;
	private DescricaoEstendida deInstance;
	
	private LazyDataModel<Projeto > pList;
	private LazyDataModel<DescricaoEstendida > deList;
	private Long idClientePortal;
	
	private String varCodigo;
	private String varNome;
	private String varCliente;
	
	public String impressao(){
		init();
		return "/views/impressao/show.xhtml";
	}
	
	@PostConstruct
	public void init(){
		deInstance = new DescricaoEstendida();
		pInstance = new Projeto();
		deList = InitUtil.inicializaDescricaoEstendidaList();
		pList = InitUtil.inicializaProjetoList();
		idClientePortal = WebUtil.getClientePortalEmContexto().getId();
	}
	
	@SuppressWarnings("serial")
	public void filtrarProjeto(){
		pList = new LazyDataModel<Projeto>() {
			@Override
			public List<Projeto> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
				WebUtil.setDataTableRows(pageSize);
				return ejb.listarProjetos(first, pageSize, sortField, 
					TipoSortOrder.convertePrimeFaces(sortOrder.toString()), idClientePortal, varCodigo, varNome, varCliente);
			}
			@Override  
	        public Projeto getRowData(String rowKey) {  
	        	try {
		            return ejb.selecionarProjeto(Long.parseLong(rowKey));
	        	} catch (NumberFormatException e){
	        		return new Projeto();
	        	}
	        }  
	        @Override  
	        public String getRowKey(Projeto objeto)  
	        {  
	        	if (objeto!=null)
	        		return ""+objeto.getId();
	        	return "";
	        }  
		};
		pList.setRowCount(ejb.countProjetos(idClientePortal, varCodigo, varNome, varCliente));
		pList.setPageSize(5);
	}
	
	public void selecionarProjeto(){
		pInstance = ejb.selecionarProjeto(pInstanceTemp.getId());
		filtrarDescricao();
		cancelarSelecionarProjeto();
	}
	
	public void cancelarSelecionarProjeto(){
		pInstanceTemp = null;
		varCodigo = null;
		varNome = null;
		varCliente = null;
		pList = InitUtil.inicializaProjetoList();
	}
	
	@SuppressWarnings("serial")
	public void filtrarDescricao(){
		deList = new LazyDataModel<DescricaoEstendida>() {
			@Override
			public List<DescricaoEstendida> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
				WebUtil.setDataTableRows(pageSize);
				return ejb.listarDescricaoEstendidas(first, pageSize, sortField, 
					TipoSortOrder.convertePrimeFaces(sortOrder.toString()), pInstance.getId());
			}
			@Override  
	        public DescricaoEstendida getRowData(String rowKey) {  
	        	try {
		            return ejb.selecionarDescricao(Long.parseLong(rowKey));
	        	} catch (NumberFormatException e){
	        		return new DescricaoEstendida();
	        	}
	        }  
	        @Override  
	        public String getRowKey(DescricaoEstendida objeto)  
	        {  
	        	if (objeto!=null)
	        		return ""+objeto.getId();
	        	return "";
	        }  
		};
		deList.setRowCount(ejb.countDescricaoEstendidas(pInstance.getId()));
		deList.setPageSize(5);
	}
	
	public void imprimirDescricao(Long idDescricao){
		deInstance = ejb.selecionarDescricao(idDescricao);

		Document doc = null;
		
		List<Dado> dadoList = ejb.selecionarDados(idDescricao);
		List<Cenario> cenarioList = ejb.selecionarCenarios(idDescricao);
		
		HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
		response.setContentType("application/pdf");      
	    response.setHeader("Content-disposition", "attachment;filename="+deInstance.getCodigo()+".pdf");
		
		try {
			doc = new Document(PageSize.A4, 30, 30, 65, 30);

			PdfDescricao pagina = new PdfDescricao(contexto.getUsuario().getNomeCompleto());
			pagina.setTituloRelatorio(deInstance.getCodigo() + " - " + deInstance.getNome());
			
			PdfWriter pdfWriter = PdfWriter.getInstance(doc, response.getOutputStream());
			pdfWriter.setPageEvent(pagina);

			doc.open();

			PdfPTable content = new PdfPTable(100);
			content.setWidthPercentage(100);

			content.addCell(label(100, "Sumário"));
			content.addCell(input(100, deInstance.getSumario()));
			content.addCell(label(25, "Risco"));
			content.addCell(label(25, "Prioridade"));
			content.addCell(label(50, "Projeto"));
			content.addCell(input(22, deInstance.getRiscoEnum()));
			content.addCell(espaco(3));
			content.addCell(input(22, deInstance.getPrioridadeEnum()));
			content.addCell(espaco(3));
			content.addCell(input(50, deInstance.getProjeto().getNome()));
			content.addCell(label(52, "Pré-Requisitos"));
			content.addCell(label(48, "Pós-Requisitos"));
			content.addCell(input(48, deInstance.getPreCondicoes()));
			content.addCell(espaco(4));
			content.addCell(input(48, deInstance.getPosCondicoes()));
			content.addCell(label(100, "Questões em Aberto"));
			content.addCell(input(100, deInstance.getQuestoesAberto()));
			content.addCell(label(100, "Regras de Negócio Associadas"));
			content.addCell(input(100, deInstance.getRegrasNegocio()));
			content.addCell(label(100, "Variações Tecnológicas"));
			content.addCell(input(100, deInstance.getVariacoesTecnologicas()));
			content.addCell(label(100, "Notas de Implementação"));
			content.addCell(input(100, deInstance.getNotasImplementacao()));
			content.addCell(label(100, "Variações Técnológias"));
			content.addCell(input(100, deInstance.getVariacoesTecnologicas()));
			
			content.addCell(espaco(100));
			content.addCell(espaco(100));
			content.addCell(espaco(100));
			
			//Tabela de Tipos de Dados
			content.addCell(headerTable(100, "Tipos de Dados"));
			content.addCell(headerRow(20, "Nome na Tela"));
			content.addCell(headerRow(5, "Edit."));
			content.addCell(headerRow(5, "Obr"));
			content.addCell(headerRow(30, "Atributo"));
			content.addCell(headerRow(10, "Tipo"));
			content.addCell(headerRow(30, "Regras"));
			
			for (Dado d:dadoList){
				content.addCell(rowTable(20, d.getNomeTela()));
				content.addCell(rowTable(5, returnString(d.getEditavel())));
				content.addCell(rowTable(5, returnString(d.getObrigatorio())));
				content.addCell(rowTable(30, d.getAtributoClasse()));
				content.addCell(rowTable(10, d.getTipoDado()));
				content.addCell(rowTable(30, d.getRegraDescricao()));
			}
			
			content.addCell(espaco(100));
			content.addCell(espaco(100));
			content.addCell(espaco(100));
			
			for (Cenario c:cenarioList){
				content.addCell(headerTable(100, c.getNome()));
				for (Fluxo f:c.getFluxos()){
					content.addCell(rowTable(10, f.getCodFluxo()));
					content.addCell(rowTable(90, f.getDescricao()));
				}
			}
			
			doc.add(content);

			doc.close();
		    FacesContext.getCurrentInstance().responseComplete();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (doc != null) {
				doc.close();
			}
		}
	}
	
	private String returnString(Boolean b){
		if (b==null)
			return "Não";
		if (b)
			return "Sim";
		return "Não";
	}
	
	private BaseColor azulEscuro = new BaseColor(29, 17, 108);
	private BaseColor azulClaro = new BaseColor(237, 237, 254);
	private Font fonteLabel = FontFactory.getFont("Arial", 10f, Font.BOLD, BaseColor.BLACK);
	private Font fonteInput = FontFactory.getFont("Arial", 10f, 0, BaseColor.BLACK);
	private Font fonteHeader = FontFactory.getFont("Arial", 11f, 0, azulEscuro);
	
	private PdfPCell label(int tam, String str){
		PdfPCell cell = new PdfPCell(new Paragraph(str, fonteLabel));
		cell.setColspan(tam);
		cell.setBorder(0);
		return cell;
	}
	
	private PdfPCell input(int tam, String str){
		PdfPCell cell = new PdfPCell(new Paragraph(str, fonteInput));
		cell.setColspan(tam);
		return cell;
	}
	
	private PdfPCell espaco(int tam){
		PdfPCell cell = new PdfPCell(new Paragraph(""));
		cell.setColspan(tam);
		cell.setBorder(0);
		return cell;
	}

	private PdfPCell headerTable(int tam, String str){
		PdfPCell cell = new PdfPCell(new Paragraph(str, fonteHeader));
		cell.setColspan(tam);
		cell.setBorder(15);
		cell.setPadding(5f);
		cell.setBorderColor(azulEscuro);
		cell.setBackgroundColor(azulClaro);
		return cell;
	}
	
	private PdfPCell headerRow(int tam, String str){
		PdfPCell cell = new PdfPCell(new Paragraph(str, fonteInput));
		cell.setColspan(tam);
		cell.setBorder(15);
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBorderColor(BaseColor.BLACK);
		cell.setBackgroundColor(azulClaro);
		return cell;
	}
	
	private PdfPCell rowTable(int tam, String str){
		PdfPCell cell = new PdfPCell(new Paragraph(str, fonteInput));
		cell.setColspan(tam);
		cell.setBorder(15);
		cell.setHorizontalAlignment(Element.ALIGN_LEFT);
		cell.setBorderColor(BaseColor.BLACK);
		return cell;
	}
	
	public String goHome(){
		destroy();
		return "goHome";
	}
	
	@PreDestroy
	public void destroy(){
		
	}

	public Projeto getpInstance() {
		return pInstance;
	}

	public void setpInstance(Projeto pInstance) {
		this.pInstance = pInstance;
	}

	public Projeto getpInstanceTemp() {
		return pInstanceTemp;
	}

	public void setpInstanceTemp(Projeto pInstanceTemp) {
		this.pInstanceTemp = pInstanceTemp;
	}

	public DescricaoEstendida getDeInstance() {
		return deInstance;
	}

	public void setDeInstance(DescricaoEstendida deInstance) {
		this.deInstance = deInstance;
	}

	public LazyDataModel<Projeto> getpList() {
		return pList;
	}

	public void setpList(LazyDataModel<Projeto> pList) {
		this.pList = pList;
	}

	public LazyDataModel<DescricaoEstendida> getDeList() {
		return deList;
	}

	public void setDeList(LazyDataModel<DescricaoEstendida> deList) {
		this.deList = deList;
	}

	public String getVarCodigo() {
		return varCodigo;
	}

	public void setVarCodigo(String varCodigo) {
		this.varCodigo = varCodigo;
	}

	public String getVarNome() {
		return varNome;
	}

	public void setVarNome(String varNome) {
		this.varNome = varNome;
	}

	public String getVarCliente() {
		return varCliente;
	}

	public void setVarCliente(String varCliente) {
		this.varCliente = varCliente;
	}

	public Long getIdClientePortal() {
		return idClientePortal;
	}

	public void setIdClientePortal(Long idClientePortal) {
		this.idClientePortal = idClientePortal;
	}
	
	
}